import {
    View,
    Image,
    Text,
    rpxToPx,
    cssValueToEnum,
    cssValueMatch,
    TaitankDirection,
    FlexDirection,
    FlexWrapMode,
    FlexAlign,
    CSSDirection,
    Dimension,
    PositionType,
    DisplayType,
    OverflowType,
    NodeType
} from "./base_view.js";

function toCamelCase(str) {
    return str.replace(/-(\w)/g, (_, letter) => letter.toUpperCase());
}

function trimQuotes(str) {
    return str.replace(/'/g, '');
}

function createInvoker(
    initialValue,
    instance
) {
    const invoker = (...args) => {
        if (Array.isArray(initialValue)) {
            initialValue.forEach((func) => {
                func.apply(instance, [...args])
            })
        } else {
            initialValue.apply(instance, [...args])
        }
    }
    invoker.value = initialValue
    initialValue.invoker = invoker
    return invoker
}

function patchProp(el, key, prevValue, nextValue, isSVG, prevChildren, parentComponent, parentSuspense, unmountChildren) {
    console.log("patchProp", JSON.stringify(key), nextValue);
    if (nextValue !== null) {
        el.props[key] = nextValue
        if (key == "style") {
            // {"width":"100rpx","height":"auto"}
            Object.keys(nextValue).forEach(pkey => {
                let camelCaseKey = toCamelCase(pkey);
                let value = trimQuotes(nextValue[pkey]);
                switch (pkey) {
                    case "background":
                        el.impl[pkey] = value;
                        break;
                    case "backgroundColor":
                        console.log("set backgroundColor from prop", pkey, value);
                        el.impl[pkey] = value;
                        break;
                    default:
                        if (cssValueMatch(camelCaseKey)) {
                            let value = cssValueToEnum(camelCaseKey, nextValue[pkey]);
                            if (camelCaseKey === "flex") {
                                el.impl.layoutProps["flexGrow"] = value.grow;
                                el.impl.layoutProps["flexShrink"] = value.shrink;
                                if (!(value.basis instanceof Number)) {
                                    el.impl.layoutProps["flexBasis"] = value.basis;
                                }
                            } else if (camelCaseKey === "flexDirection") {
                                el.impl.layoutProps["flexDirection"] = value;
                                console.log("flexDirection", el.impl.layoutProps.flexDirection);
                            } else if (camelCaseKey === 'margin') {
                                el.impl.layoutProps[camelCaseKey] = value;
                                // console.log("flexDirection", el.impl.layoutProps.flexDirection);
                            }
                            else {
                                console.log("no special, value not match", value, typeof value, value instanceof Number, value instanceof String, camelCaseKey);
                                el.impl.layoutProps[camelCaseKey] = value;
                            }
                        } else {
                            let value = nextValue[pkey];
                            switch (pkey) {
                                case "width":
                                case "height":
                                    if (value.endsWith("rpx")) {
                                        const num = value.replace(/rpx/g, '')
                                        console.log(pkey, num);
                                        el.impl.layoutProps[camelCaseKey] = rpxToPx(parseFloat(num));
                                    } else if (value.endsWith("vh") || value.endsWith("vw")) {
                                        const num = value.endsWith("vh") ? value.replace(/vh/g, '') : value.replace(/vw/g, '')
                                        console.log(pkey, value, num);
                                        const v = parseFloat(num) * (value.endsWith("vh") ? window.screen.height : window.screen.width) / 100;
                                        el.impl.layoutProps[camelCaseKey] = v;
                                    } else {
                                        const num = value.replace(/px/g, '')
                                        console.log(pkey, num);
                                        el.impl.layoutProps[camelCaseKey] = parseFloat(num);
                                    }
                                    break;
                                case "color":
                                    value = value.replace(/'/g, '');
                                    console.log("color", value, nextValue)
                                    el.impl.color = value;
                                    break;
                                case "backgroundColor":
                                    el.impl[pkey] = value;
                                    console.log("set backgroundColor", pkey, value);
                                    break;
                                default:

                                    break;
                            }
                            // console.log(`set element style property: ${camelCaseKey}: ${nextValue[pkey]}, ${value}`);
                        }
                        break;
                }
            });
        } else if (key == "class") {
            console.log("class style: ", nextValue);
        } else if (key == "onClick") {
            console.log("onClick will set ", nextValue, prevChildren);
            const value = nextValue
            const invoker = prevValue && prevValue.invoker
            if (nextValue && value) {
                if (invoker) {
                    prevValue.invoker = null
                    invoker.value = value
                    nextValue.invoker = invoker
                } else {
                    let nInvoker = createInvoker(value, parentComponent);
                    el.impl.setOnClickListener(nInvoker);
                }
            } else if (invoker) {
                console.log("invoker need remove");
            }
        } else if (key == "src") {
            console.log("src ", nextValue, trimQuotes(nextValue));
            el.impl.src = trimQuotes(nextValue);
        } else {
        }
    } else {
        delete el.props[key] // 处理属性移除
    }
}

export {
    patchProp as patchPropImpl
};
